<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <title>script.aculo.us Unit test file</title>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <script src="../../lib/prototype.js" type="text/javascript"></script>
  <script src="../../src/scriptaculous.js" type="text/javascript"></script>
  <script src="../../src/unittest.js" type="text/javascript"></script>
  <link rel="stylesheet" href="../test.css" type="text/css" />
</head>
<body>
<h1>script.aculo.us Unit test file</h1>
<p>
  Tests for <code>Ajax.InPlaceEditor</code> and <code>Ajax.InPlaceCollectionEditor</code> in controls.js
</p>

<!-- Log output -->
<div id="testlog"> </div>

<h1 id="tobeedited">To be edited</h1>
<a id="tobeeditedEditControl" href="#">edit</a>

<p id="newtbe">New to be edited</p>
<p id="newtbe_external">External control for it</p>

<p id="contains_ampersand">Me & Myself</p>

<div id="tobeeditedMultiLine">First line<br/>
Second line<br/>
Third line</div>

<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[

  var IPCE_COLLECTION = [
    ['tbe',   'To be edited'],
    ['ntbe',  'New to be edited'],
    ['ntbe2', 'New to be edited 2'],
    ['ntbe3', 'New to be edited 3']
  ];

  new Test.Unit.Runner({

    setup: function() { with(this) {
      inPlaceEditor = new Ajax.InPlaceEditor($('tobeedited'), '_ajax_inplaceeditor_result.html', {
        externalControl: $('tobeeditedEditControl'),
        ajaxOptions: {method: 'get'} //override so we can use a static for the result
      });
      inPlaceEditorMultiLine = new Ajax.InPlaceEditor($('tobeeditedMultiLine'), '_ajax_inplaceeditor_result.html', {
        ajaxOptions: {method: 'get'} //override so we can use a static for the result
      });
    }},

    teardown: function() { with(this) {
      inPlaceEditor.dispose();
      inPlaceEditorMultiLine.dispose();
    }},

    // Original-version tests, still pass thx to backward compatibility

    // Integration test, tests the entire cycle
    testInPlaceEditor: function() { with(this) {
      Event.simulateMouse('tobeedited','click');
      assertHidden($('tobeedited'));
      assertNotNull(document.forms[0]);
      assertEqual("cancel", document.forms[0].lastChild.innerHTML);
      assertVisible(document.forms[0]);

      Event.simulateMouse(document.forms[0].lastChild,'click');
      assertNull(document.forms[0]);
      assertVisible($('tobeedited'));
      assertEqual("transparent", Element.getStyle('tobeedited','background-color'));
      Event.simulateMouse('tobeedited','mouseover');
      Event.simulateMouse('tobeedited','click');

      assertEqual("INPUT", document.forms[0].firstChild.tagName);
      assertEqual("To be edited", document.forms[0].firstChild.value);
      assertEqual("INPUT", document.forms[0].childNodes[1].tagName);
      assertEqual("submit", document.forms[0].childNodes[1].type);
      assertEqual("To be edited", document.forms[0].firstChild.value);
      assert(Element.hasClassName(document.forms[0], 'inplaceeditor-form'),
        "form doesn't have proper class: " + document.forms[0].className);

      Event.simulateMouse(document.forms[0].childNodes[1],'click');

      assertVisible($('tobeedited'));
      assertEqual("Saving...", $('tobeedited').innerHTML);
      assertEqual("transparent", Element.getStyle('tobeedited','background-color'));
      assert(Element.hasClassName($('tobeedited'), 'inplaceeditor-saving'),
        "doesn't have saving class");

      wait(1000, function() {
        assertEqual("Server received: To be edited", $('tobeedited').innerHTML);
        assertNull(document.forms[0]);
        assertVisible($('tobeedited'));
        assert(!Element.hasClassName($('tobeedited'), 'inplaceeditor-saving'));
      });
    }},

    testHovering: function() { with(this) {
      Event.simulateMouse('tobeedited','mouseover');
      assertEqual("rgb(255, 255, 153)", Element.getStyle('tobeedited','background-color'));

      Event.simulateMouse('tobeedited','mouseout');
      wait(1100, function() {
        assertEqual("transparent", Element.getStyle('tobeedited','background-color'),
          "should be transparent after mouse leaves element");

        Event.simulateMouse('tobeedited','click');
      })
    }},

    testLoadsTextFromServer: function() { with(this) {
      inPlaceEditor.options.loadTextURL = '_ajax_inplaceeditor_text.html';
      inPlaceEditor.enterEditMode();
      assertEqual('Loading...', inPlaceEditor._form.value.value);
      assert(inPlaceEditor._form.value.disabled);
      assert(Element.hasClassName(inPlaceEditor._form, 'inplaceeditor-loading'));
      wait(1000, function() {
        assertEqual('Text from server', inPlaceEditor._form.value.value);
        assert(!inPlaceEditor._form.value.disabled);
      });
    }},

    testDisposesProperly: function() { with(this) {
      assertEqual("transparent", Element.getStyle('tobeedited','background-color'));
      inPlaceEditor.dispose();
      assertEqual("transparent", Element.getStyle('tobeedited','background-color'));
      assertVisible($('tobeedited'));
      Event.simulateMouse('tobeedited','click');
      assertVisible($('tobeedited'));
    }},

    testUsesTextAreaWhenMoreThanOneRows: function() { with(this) {
      inPlaceEditor.options.rows = 5;
      inPlaceEditor.enterEditMode();
      assertEqual("TEXTAREA", document.forms[0].firstChild.tagName);
      assertEqual("BR", document.forms[0].childNodes[1].tagName);
    }},

    testCanSpecifyAllTextsThroughOptions: function() { with(this) {
       // swedish translation ;-)
      inPlaceEditor.options.okText = "spara";
      inPlaceEditor.options.cancelText = "avbryt";
      inPlaceEditor.options.savingText = "Sparar...";
      inPlaceEditor.enterEditMode();
      assertEqual("spara", document.forms[0].lastChild.previousSibling.value);
      assertEqual("avbryt", document.forms[0].lastChild.innerHTML);
      inPlaceEditor.showSaving();
      assertEqual("Sparar...", $('tobeedited').innerHTML);
    }},

    testCanSpecifyFormIdThroughOptions: function() { with(this) {
      inPlaceEditor.enterEditMode();
      // default form id
      assertEqual("tobeedited-inplaceeditor", document.forms[0].id);
      inPlaceEditor.leaveEditMode();
      inPlaceEditor.options.formId = "myFormId";
      inPlaceEditor.enterEditMode();
      assertEqual("myFormId", document.forms[0].id);
    }},

    testCantEditWhileSaving: function() { with(this) {
      inPlaceEditor.prepareSubmission();
      Event.simulateMouse('tobeedited','mouseover');
      assertEqual("transparent", Element.getStyle('tobeedited','background-color'));
      Event.simulateMouse('tobeedited','click');
      assertVisible($('tobeedited'));
    }},

    testCallbackFunctionGetsCalled: function() { with(this) {
      var called = false;
      inPlaceEditor.options.callback = function(form) {
        called = true;
      }
      Event.simulateMouse('tobeedited','click');
      Event.simulateMouse(document.forms[0].childNodes[1],'click');
      assert(called, "callback was not called");
    }},

    testCanUseExternalElementToGoIntoEditMode: function() { with(this) {
      Event.simulateMouse('tobeeditedEditControl','click');
      assertNotNull(document.forms[0], "external control didn't work");
      // doesn't work if you click it again while in edit mode
      Event.simulateMouse('tobeeditedEditControl','click');
      assertNull(document.forms[1], "external control created two forms");
      assertNotVisible($('tobeeditedEditControl'));
      Event.simulateMouse(document.forms[0].childNodes[2],'click');
      assertVisible($('tobeeditedEditControl'));
    }},

    // Rewritten-version tests
    testControlOptions: function() {with(this) {
      // Default, then explicit default-equivalent, settings
      [{}, { okControl: 'button', cancelControl: 'link' }].each(function(opts) {
        var ipe = new Ajax.InPlaceEditor('newtbe', '', opts);
        Event.simulateMouse('newtbe', 'click');
        var submits = $('newtbe-inplaceeditor').getInputs('submit');
        assertEqual(1, submits.length, 'Not just one submit');
        assertEqual(Ajax.InPlaceEditor.DefaultOptions.okText, submits[0].value, 'Incorrect button label');
        assert(submits[0].hasClassName('editor_ok_button'), 'Missing class name on ok button');
        var links = $$('#newtbe-inplaceeditor a');
        assertEqual(1, links.length, 'Not just one link');
        assertEqual(Ajax.InPlaceEditor.DefaultOptions.cancelText, links[0].firstChild.nodeValue, 'Incorrect cancel link text');
        assert(links[0].href.endsWith('#'), 'Incorrect cancel link href');
        assert(links[0].hasClassName('editor_cancel_link'), 'Missing class name on cancel link');
        ipe.dispose();
      });
      // Reverse: ok link, cancel button
      var ipe = new Ajax.InPlaceEditor('newtbe', '', { okControl: 'link', cancelControl: 'button' });
      Event.simulateMouse('newtbe', 'click');
      var links = $$('#newtbe-inplaceeditor a');
      assertEqual(1, links.length, 'Not just one link');
      assertEqual(Ajax.InPlaceEditor.DefaultOptions.okText, links[0].firstChild.nodeValue, 'Incorrect ok link text');
      assert(links[0].href.endsWith('#'), 'Incorrect ok link href');
      assert(links[0].hasClassName('editor_ok_link'), 'Missing class name on ok link');
      var submits = $('newtbe-inplaceeditor').getInputs('submit');
      assertEqual(1, submits.length, 'Not just one submit');
      assertEqual(Ajax.InPlaceEditor.DefaultOptions.cancelText, submits[0].value, 'Incorrect button label');
      assert(submits[0].hasClassName('editor_cancel_button'), 'Missing class name on cancel button');
      ipe.dispose();
      // Full links
      ipe = new Ajax.InPlaceEditor('newtbe', '', { okControl: 'link' });
      Event.simulateMouse('newtbe', 'click');
      var links = $$('#newtbe-inplaceeditor a');
      assertEqual(2, links.length, 'There should be two links');
      assertEqual(Ajax.InPlaceEditor.DefaultOptions.okText, links[0].firstChild.nodeValue, 'Incorrect ok link text');
      assertEqual(Ajax.InPlaceEditor.DefaultOptions.cancelText, links[1].firstChild.nodeValue, 'Incorrect cancel link text');
      assert(links[0].href.endsWith('#'), 'Incorrect ok link href');
      assert(links[1].href.endsWith('#'), 'Incorrect cancel link href');
      assert(links[0].hasClassName('editor_ok_link'), 'Missing class name on ok link');
      assert(links[1].hasClassName('editor_cancel_link'), 'Missing class name on cancel link');
      var submits = $('newtbe-inplaceeditor').getInputs('submit');
      assertEqual(0, submits.length, 'There should be no submit');
      ipe.dispose();
      // Full buttons
      ipe = new Ajax.InPlaceEditor('newtbe', '', { cancelControl: 'button' });
      Event.simulateMouse('newtbe', 'click');
      var submits = $('newtbe-inplaceeditor').getInputs('submit');
      assertEqual(2, submits.length, 'There should be two submits');
      assertEqual(Ajax.InPlaceEditor.DefaultOptions.okText, submits[0].value, 'Incorrect ok button text');
      assertEqual(Ajax.InPlaceEditor.DefaultOptions.cancelText, submits[1].value, 'Incorrect cancel button text');
      assert(submits[0].hasClassName('editor_ok_button'), 'Missing class name on ok button');
      assert(submits[1].hasClassName('editor_cancel_button'), 'Missing class name on cancel button');
      var links = $$('#newtbe-inplaceeditor a');
      assertEqual(0, links.length, 'There should be no link');
      ipe.dispose();
      // No cancel
      ipe = new Ajax.InPlaceEditor('newtbe', '', { cancelControl: false });
      Event.simulateMouse('newtbe', 'click');
      var submits = $('newtbe-inplaceeditor').getInputs('submit');
      assertEqual(1, submits.length, 'Not just one submit');
      var links = $$('#newtbe-inplaceeditor a');
      assertEqual(0, links.length, 'There should be no link');
      ipe.dispose();
      // No OK
      ipe = new Ajax.InPlaceEditor('newtbe', '', { okControl: false });
      Event.simulateMouse('newtbe', 'click');
      var submits = $('newtbe-inplaceeditor').getInputs('submit');
      assertEqual(0, submits.length, 'There should be no submit');
      var links = $$('#newtbe-inplaceeditor a');
      assertEqual(1, links.length, 'Not just one link');
      ipe.dispose();
      // Nothing
      ipe = new Ajax.InPlaceEditor('newtbe', '', { okControl: false, cancelControl: false });
      Event.simulateMouse('newtbe', 'click');
      var submits = $('newtbe-inplaceeditor').getInputs('submit');
      assertEqual(0, submits.length, 'There should be no submit');
      var links = $$('#newtbe-inplaceeditor a');
      assertEqual(0, links.length, 'There should be no link');
      ipe.dispose();
      // Texts: default mode
      ipe = new Ajax.InPlaceEditor('newtbe', '', { okControl: false, cancelControl: false });
      Event.simulateMouse('newtbe', 'click');
      var submits = $('newtbe-inplaceeditor').getInputs('submit');
      assertEqual(0, submits.length, 'There should be no submit');
      var links = $$('#newtbe-inplaceeditor a');
      assertEqual(0, links.length, 'There should be no link');
      ipe.dispose();
      // Texts: before w/ controls
      ipe = new Ajax.InPlaceEditor('newtbe', '', { textBeforeControls: '[' });
      Event.simulateMouse('newtbe', 'click');
      var text = $('newtbe-inplaceeditor').childNodes[1];
      assertEqual(3, text.nodeType, 'Missing/misplaced initial text');
      assertEqual('[', text.nodeValue, 'Incorrect text');
      ipe.dispose();
      // Texts: after w/ controls
      ipe = new Ajax.InPlaceEditor('newtbe', '', { textAfterControls: ']' });
      Event.simulateMouse('newtbe', 'click');
      var text = $('newtbe-inplaceeditor').childNodes[3];
      assertEqual(3, text.nodeType, 'Missing/misplaced final text');
      assertEqual(']', text.nodeValue, 'Incorrect text');
      ipe.dispose();
      // Texts: between w/ controls
      ipe = new Ajax.InPlaceEditor('newtbe', '', { textBetweenControls: ' ' });
      Event.simulateMouse('newtbe', 'click');
      var text = $('newtbe-inplaceeditor').childNodes[2];
      assertEqual(3, text.nodeType, 'Missing/misplaced middle text');
      assertEqual(' ', text.nodeValue, 'Incorrect text');
      ipe.dispose();
      // Texts: before w/ no control
      ipe = new Ajax.InPlaceEditor('newtbe', '', { textBeforeControls: '[', okControl: false, cancelControl: false });
      Event.simulateMouse('newtbe', 'click');
      var nodes = $('newtbe-inplaceeditor').childNodes;
      assertEqual(1, nodes.length, 'Too many nodes in the form.');
      ipe.dispose();
      // Texts: after w/ no control
      ipe = new Ajax.InPlaceEditor('newtbe', '', { textAfterControls: ']', okControl: false, cancelControl: false });
      Event.simulateMouse('newtbe', 'click');
      var nodes = $('newtbe-inplaceeditor').childNodes;
      assertEqual(1, nodes.length, 'Too many nodes in the form.');
      ipe.dispose();
      // Texts: between w/ less than two controls
      ipe = new Ajax.InPlaceEditor('newtbe', '', { textBetweenControls: ' ', okControl: false });
      Event.simulateMouse('newtbe', 'click');
      var nodes = $('newtbe-inplaceeditor').childNodes;
      assertEqual(2, nodes.length, 'The form should have only two nodes (edit+cancel)');
      assertEnumEqual(['input', 'a'], $A(nodes).pluck('tagName').invoke('toLowerCase'), 'Incorrect nodes');
      ipe.dispose();
    }},

    testExternalControlOnly: function() {with(this) {
      var ipe = new Ajax.InPlaceEditor('newtbe', '_ajax_inplaceeditor_result2.html', {
        externalControl: 'newtbe_external'
      });
      Event.simulateMouse('newtbe', 'click');
      assert(ipe._editing, 'Clicking on the element should turn editable.');
      ipe.leaveEditMode();
      Event.simulateMouse('newtbe_external', 'click');
      assert(ipe._editing, 'Clicking on the external control should turn editable.');
      ipe.dispose();
      ipe = new Ajax.InPlaceEditor('newtbe', '_ajax_inplaceeditor_result2.html', {
        externalControl: 'newtbe_external', externalControlOnly: true
      });
      Event.simulateMouse('newtbe', 'click');
      assert(!ipe._editing, 'Clicking on the element should not turn editable.');
      Event.simulateMouse('newtbe_external', 'click');
      assert(ipe._editing, 'Clicking on the external control should turn editable.');
      ipe.dispose();
    }},

    testNewCallbacks: function() {with(this) {
      var called = [];
      var opts = {
        onEnterHover: function() { called.push('onEnterHover') },
        onEnterEditMode: function() { called.push('onEnterEditMode') },
        onLeaveEditMode: function() { called.push('onLeaveEditMode') },
        callback: function(form) {
          called.push('callback');
          return form.serialize();
        },
        onFailure: function() { called.push('onFailure') },
        onComplete: function() { called.push('onComplete') },
        onLeaveEditMode: function() { called.push('onLeaveEditMode') }
      }
      // Proper success
      $('newtbe').update('New to be edited');
      var ipe = new Ajax.InPlaceEditor('newtbe', '_ajax_inplaceeditor_result2.html', opts);
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      Event.simulateKey('newtbe', 'keydown', { keyCode: Event.KEY_RETURN });
      var postUpdateHTML;
      wait(1000, function() {
        assertEnumEqual(['onEnterHover', 'onEnterEditMode', 'callback', 'onLeaveEditMode', 'onComplete'],
          called.uniq(), 'Incorrect callback sequence');
        postUpdateHTML = $('newtbe').innerHTML.strip();
        assertEqual('New to be edited - edited', postUpdateHTML, 'Update trouble');
        ipe.dispose();
        // Failure
        called.clear();
        // Any ideas?  Requesting file:// URLs on non-existent stuff doesn't trigger A.U's onFailure...
      });
    }},

    testCallbackFunctionReturnTypes: function() { with(this) {
      var params = [];
      var responder = {
        onCreate: function(req) {
          params.push(req.options.parameters);
        }
      };
      Ajax.Responders.register(responder);
      var ipe = new Ajax.InPlaceEditor('newtbe', '_ajax_inplaceeditor_result2.html', {
        callback: function(form) {
          return 'foo=bar';
        }
      });
      Event.simulateMouse('newtbe', 'click');
      Event.simulateKey('newtbe', 'keydown', { keyCode: Event.KEY_RETURN });
      wait(200, function() {
        assert(params[0] && params[0].foo == 'bar');
        ipe.dispose();
        ipe = new Ajax.InPlaceEditor('newtbe', '_ajax_inplaceeditor_result2.html', {
          callback: function(form) {
            return { bar: '?', 'r&d': 42 };
          }
        });
        Event.simulateMouse('newtbe', 'click');
        Event.simulateKey('newtbe', 'keydown', { keyCode: Event.KEY_RETURN });
        wait(200, function() {
          assert(params[1] && params[1].bar == '?' && params[1]['r&d'] == 42);
          ipe.dispose();
          Ajax.Responders.unregister(responder);
        })
      });
    }},

    testHtmlResponse: function() {with(this) {
      // Default (true) -> A.U w/ evalScripts: true
      $('newtbe').update('New to be edited');
      var ipe = new Ajax.InPlaceEditor('newtbe', '_ajax_inplaceeditor_result2.html');
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      Event.simulateKey('newtbe', 'keydown', { keyCode: Event.KEY_RETURN });
      var postUpdateHTML;
      wait(1000, function() {
        postUpdateHTML = $('newtbe').innerHTML.strip();
        assertEqual('New to be edited - edited', postUpdateHTML, 'Should have updated contents');
        ipe.dispose();
        // Explicit htmlResponse: true -> A.U w/ evalScripts: true
        $('newtbe').update('New to be edited');
        ipe = new Ajax.InPlaceEditor('newtbe', '_ajax_inplaceeditor_result2.html', { htmlResponse: true });
        Event.simulateMouse('newtbe', 'mouseover');
        Event.simulateMouse('newtbe', 'click');
        Event.simulateKey('newtbe', 'keydown', { keyCode: Event.KEY_RETURN });
        wait(1000, function() {
          postUpdateHTML = $('newtbe').innerHTML.strip();
          assertEqual('New to be edited - edited', postUpdateHTML, 'Should have updated contents');
          ipe.dispose();
          // Explicit htmlResponse: false -> A.R
          $('newtbe').update('New to be edited');
          ipe = new Ajax.InPlaceEditor('newtbe', '_ajax_inplaceeditor_result2.html', { htmlResponse: false });
          Event.simulateMouse('newtbe', 'mouseover');
          Event.simulateMouse('newtbe', 'click');
          Event.simulateKey('newtbe', 'keydown', { keyCode: Event.KEY_RETURN });
          wait(1000, function() {
            postUpdateHTML = $('newtbe').innerHTML.strip();
            assertEqual(ipe.options.savingText, postUpdateHTML, 'Should not have updated contents');
            ipe.dispose();
          });
        });
      });
    }},

    testSingleOrMultipleRows: function() {with(this) {
      // Single-line value, rows <= 1 -> 1
      $('newtbe').update('New to be edited');
      var ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html');
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      assertEqual('input', ipe._controls.editor.tagName.toLowerCase());
      ipe.dispose();
      // Single-line value, rows > 1 (2) -> 2
      var ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { rows: 2 });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      assertEqual('textarea', ipe._controls.editor.tagName.toLowerCase());
      assertEqual(2, ipe._controls.editor.rows);
      ipe.dispose();
      // Multiple-line value, rows <= 1, autoRows default (3) -> 3
      $('newtbe').update('Line 1\nLine 2\nLine 3');
      var ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html');
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      assertEqual('textarea', ipe._controls.editor.tagName.toLowerCase());
      assertEqual(Ajax.InPlaceEditor.DefaultOptions.autoRows, ipe._controls.editor.rows);
      ipe.dispose();
      // Multiple-line value, rows <= 1, autoRows custom (5) -> 5
      var ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { autoRows: 5 });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      assertEqual('textarea', ipe._controls.editor.tagName.toLowerCase());
      assertEqual(5, ipe._controls.editor.rows);
      ipe.dispose();
      // Multiple-line value, rows > 1 (2), autoRows default (3) -> 2
      var ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { rows: 2 });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      assertEqual('textarea', ipe._controls.editor.tagName.toLowerCase());
      assertEqual(2, ipe._controls.editor.rows);
      ipe.dispose();
      // Multiple-line value, rows > 1 (2), autoRows custom (5) -> 2
      var ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { rows: 2, autoRows: 5 });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      assertEqual('textarea', ipe._controls.editor.tagName.toLowerCase());
      assertEqual(2, ipe._controls.editor.rows);
      ipe.dispose();
    }},

    testFormCustomizationCallback: function() {with(this) {
      var ipe = new Ajax.InPlaceEditor('newtbe', '_ajax_inplaceeditor_result2.html', {
        onFormCustomization: function(ipe, form) {
          form.appendChild(new Element('input', { type: 'text', name: 'test', value: 'foobar' }));
        }
      });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      assertEqual('foobar', Form.serialize(ipe._form, true).test, 'Custom field not present');
      ipe.dispose();
    }},

    testPostCreationBehavior: function() {with(this) {
      var focused = false, activated = false;
      function override(name, fx) {
        arguments.callee.backups[name] = Field.Methods[name];
        Field.Methods[name] = fx;
      };
      override.backups = {};
      function restore() {
        $A(arguments).each(function(n) {
          Field.Methods[name] = override.backups[name];
        });
        Element.addMethods();
      };
      override('activate', function(elt) {
        override.backups['activate'](elt);
        activated = true;
      });
      override('focus', function(elt) { focused = true; });
      Element.addMethods();
      // fieldPostCreation default (activate)
      var ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html');
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      assert(focused && activated, "Should be focused and activated (resp. " + focused + " and " + activated + ')');
      ipe.dispose();
      // fieldPostCreation == 'focus'
      focused = activated = false;
      ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { fieldPostCreation: 'focus' });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      assert(focused && !activated, "Should be focused, not activated (resp. " + focused + " and " + activated + ')');
      ipe.dispose();
      // fieldPostCreation == false
      focused = activated = false;
      ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { fieldPostCreation: false });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      assert(!focused && !activated, "Should be neither focused nor activated (resp. " + focused + " and " + activated + ')');
      ipe.dispose();
      // fieldPostCreation == non-false yet neither activate nor focus -> default
      focused = activated = false;
      ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { fieldPostCreation: 'foobar' });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      assert(focused && activated, "Should be focused and activated (resp. " + focused + " and " + activated + ')');
      ipe.dispose();
      restore('activate', 'focus');
    }},

    testResponseTagStripping: function() {with(this) {
      // stripLoadedTextTags default (false)
      var ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html',
        { loadTextURL: '_ajax_inplaceeditor_tagged.html' });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      wait(1000, function() {
        assertEqual('<span>New to be edited - edited</span>', ipe._controls.editor.value.strip());
        ipe.dispose();
        // stripLoadedTextTags == true
        ipe = new Ajax.InPlaceEditor('newtbe',
          '_ajax_inplaceeditor_result2.html',
          { loadTextURL: '_ajax_inplaceeditor_tagged.html',
            stripLoadedTextTags: true });
        Event.simulateMouse('newtbe', 'mouseover');
        Event.simulateMouse('newtbe', 'click');
        wait(1000, function() {
          assertEqual('New to be edited - edited', ipe._controls.editor.value.strip());
          ipe.dispose();
        });
      });
    }},

    testSubmitOnBlur: function() {with(this) {
      // submitOnBlur default (false)
      $('newtbe').update('To be edited');
      var ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html');
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      ipe._controls.editor.blur();
      wait(1000, function() {
        assertEqual('To be edited', ipe._controls.editor ?  ipe._controls.editor.value : '');
        ipe.dispose();
        // submitOnBlur == true
        ipe = new Ajax.InPlaceEditor('newtbe',
          '_ajax_inplaceeditor_result2.html', { submitOnBlur: true });
        Event.simulateMouse('newtbe', 'mouseover');
        Event.simulateMouse('newtbe', 'click');
        ipe._controls.editor.blur();
        wait(1200, function() {
          assertEqual('New to be edited - edited', $('newtbe').innerHTML.strip());
          ipe.dispose();
        });
      });
    }},

    testEscReturnKeys: function() {with(this) {
      // No controls, Esc
      var ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { okControl: false, cancelControl: false});
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      Event.simulateKey('newtbe', 'keydown', { keyCode: Event.KEY_ESC });
      assert(!ipe._editing, 'Esc should have disabled IPE');
      ipe.dispose();
      // Cancel control, Esc
      var ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { okControl: false });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      Event.simulateKey('newtbe', 'keydown', { keyCode: Event.KEY_ESC });
      assert(!ipe._editing, 'Esc should have disabled IPE');
      ipe.dispose();
      // OK control, Esc
      var ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { cancelControl: false });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      Event.simulateKey('newtbe', 'keydown', { keyCode: Event.KEY_ESC });
      assert(!ipe._editing, 'Esc should have disabled IPE');
      ipe.dispose();
      // Both controls, Esc
      ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html');
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      Event.simulateKey('newtbe', 'keydown', { keyCode: Event.KEY_ESC });
      assert(!ipe._editing, 'Esc should have disabled IPE');
      ipe.dispose();
      // No controls, Return
      $('newtbe').update('New to be edited');
      ipe = new Ajax.InPlaceEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { okControl: false, cancelControl: false });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      Event.simulateKey('newtbe', 'keydown', { keyCode: Event.KEY_RETURN });
      wait(1000, function() {
        assertEqual('New to be edited - edited', $('newtbe').innerHTML.strip());
        ipe.dispose();
        // Cancel control, Return
        $('newtbe').update('New to be edited');
        ipe = new Ajax.InPlaceEditor('newtbe',
          '_ajax_inplaceeditor_result2.html', { okControl: false });
        Event.simulateMouse('newtbe', 'mouseover');
        Event.simulateMouse('newtbe', 'click');
        Event.simulateKey('newtbe', 'keydown', { keyCode: Event.KEY_RETURN });
        wait(1000, function() {
          assertEqual('New to be edited - edited', $('newtbe').innerHTML.strip());
          ipe.dispose();
          // OK control, Return
          $('newtbe').update('New to be edited');
          ipe = new Ajax.InPlaceEditor('newtbe',
            '_ajax_inplaceeditor_result2.html', { cancelControl: false });
          Event.simulateMouse('newtbe', 'mouseover');
          Event.simulateMouse('newtbe', 'click');
          Event.simulateKey('newtbe', 'keydown', { keyCode: Event.KEY_RETURN });
          wait(1000, function() {
            assertEqual('New to be edited - edited', $('newtbe').innerHTML.strip());
            ipe.dispose();
            // Both controls, Return
            $('newtbe').update('New to be edited');
            ipe = new Ajax.InPlaceEditor('newtbe',
              '_ajax_inplaceeditor_result2.html');
            Event.simulateMouse('newtbe', 'mouseover');
            Event.simulateMouse('newtbe', 'click');
            Event.simulateKey('newtbe', 'keydown', { keyCode: Event.KEY_RETURN });
            wait(1000, function() {
              assertEqual('New to be edited - edited', $('newtbe').innerHTML.strip());
              ipe.dispose();
            });
          });
        });
      });
    }},

    testIPCEBasic: function() {with(this) {
      // Basic creation, population and choice.
      $('newtbe').update('ntbe');
      var fieldValue = '';
      var ipe = new Ajax.InPlaceCollectionEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { paramName: 'test',
        collection: IPCE_COLLECTION, callback: function(f, value) {
          fieldValue = value;
        }, onComplete: Prototype.emptyFunction
      });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      var editor = ipe._controls.editor;
      assertEqual('test', editor.name);
      assertEqual('select', editor.tagName.toLowerCase());
      assertEqual(IPCE_COLLECTION.length, editor.options.length, 'Incorrect amount of options');
      for (var index = 0; index < IPCE_COLLECTION.length; ++index) {
        var ref = IPCE_COLLECTION[index];
        var item = editor.options[index];
        assertEqual(ref[0], item.value, 'Incorrect OPTION value');
        assertEqual(ref[1], item.text.strip(), 'Incorrect OPTION text');
      };
      assertEqual(1, editor.selectedIndex, 'Did not properly select item');
      editor.selectedIndex = 2;
      Event.simulateMouse(ipe._controls.ok, 'click');
      assertEqual('ntbe2', fieldValue);
      ipe.dispose();
      // Test the value option
      $('newtbe').update('ntbe');
      ipe = new Ajax.InPlaceCollectionEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { paramName: 'test',
        collection: IPCE_COLLECTION, onComplete: Prototype.emptyFunction,
        value: 'ntbe2'
      });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      editor = ipe._controls.editor;
      assertEqual(2, editor.selectedIndex, 'Did not properly select item');
      ipe.dispose();
    }},

    testIPCECollectionSyntaxes: function() {with(this) {
      // Array of two-item arrays (0 = value, 1 = text)
      $('newtbe').update('ntbe');
      var ipe = new Ajax.InPlaceCollectionEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { paramName: 'test',
        collection: IPCE_COLLECTION, onComplete: Prototype.emptyFunction
      });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      var editor = ipe._controls.editor;
      assertEqual(1, editor.selectedIndex, 'Did not properly select item');
      // (further contents testing already done in Basic)
      ipe.dispose();
      // Array of one-item arrays
      ipe = new Ajax.InPlaceCollectionEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { paramName: 'test',
        collection: [['tbe'], ['ntbe'], ['ntbe2'], ['ntbe3']],
        onComplete: Prototype.emptyFunction
      });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      var editor = ipe._controls.editor;
      assertEqual(1, editor.selectedIndex, 'Did not properly select item');
      assertEqual('ntbe', $F(editor).strip(), 'Did not properly define text');
      ipe.dispose();
      // Array of items
      ipe = new Ajax.InPlaceCollectionEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { paramName: 'test',
        collection: ['tbe', 'ntbe', 'ntbe2', 'ntbe3'],
        onComplete: Prototype.emptyFunction
      });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      var editor = ipe._controls.editor;
      assertEqual(1, editor.selectedIndex, 'Did not properly select item');
      assertEqual('ntbe', $F(editor).strip(), 'Did not properly define text');
      ipe.dispose();
    }},

    testIPCEAlternateTextOptions: function() {with(this) {
      // loadTextURL (check loading text, verify alternate text eventually)
      $('newtbe').update('New to be edited');
      var ipe = new Ajax.InPlaceCollectionEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { paramName: 'test',
        collection: IPCE_COLLECTION, loadTextURL: '_ajax_inplaceeditor_ipce_alt_text.html',
        onComplete: Prototype.emptyFunction
      });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      var editor = ipe._controls.editor;
      var text = editor.options[editor.selectedIndex].text.strip();
      assertEqual(Ajax.InPlaceEditor.DefaultOptions.loadingText, text);
      wait(1200, function() {
        assertEqual(1, editor.selectedIndex, 'Did not properly select item based on alternate text.');
        ipe.dispose();
      });
    }},

    testIPCEDynamicCollectionOptions: function() {with(this) {
      // loadCollectionURL, default loadingCollectionText
      $('newtbe').update('ntbe');
      var ipe = new Ajax.InPlaceCollectionEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { paramName: 'test',
        loadCollectionURL: '_ajax_inplaceeditor_ipce_collection.js',
        onComplete: Prototype.emptyFunction
      });
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      var editor = ipe._controls.editor;
      var text = editor.options[editor.selectedIndex].text.strip();
      assertEqual(Ajax.InPlaceCollectionEditor.DefaultOptions.loadingCollectionText, text);
      wait(1000, function() {
        assertEqual(5, ipe._collection.length);
        assertEqual(2, editor.selectedIndex, 'Did not properly select item');
        ipe.dispose();
        // loadCollectionURL, custom loadingCollectionText
        $('newtbe').update('bar');
        ipe = new Ajax.InPlaceCollectionEditor('newtbe',
          '_ajax_inplaceeditor_result2.html', { paramName: 'test',
          loadCollectionURL: '_ajax_inplaceeditor_ipce_collection.js',
          loadingCollectionText: 'There we go...',
          onComplete: Prototype.emptyFunction
        });
        Event.simulateMouse('newtbe', 'mouseover');
        Event.simulateMouse('newtbe', 'click');
        editor = ipe._controls.editor;
        text = editor.options[editor.selectedIndex].text.strip();
        assertEqual('There we go...', text);
        wait(1000, function() {
          assertEqual(1, editor.selectedIndex, 'Did not properly select item');
          ipe.dispose();
        });
      });
    }},

    testIPCEATPlusDC: function() {with(this) {
      // loadCollectionURL, loadTextURL
      $('newtbe').update('Like I care');
      var ipe = new Ajax.InPlaceCollectionEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { paramName: 'test',
        loadCollectionURL: '_ajax_inplaceeditor_ipce_collection.js',
        loadingCollectionText: 'There we go...',
        loadTextURL: '_ajax_inplaceeditor_ipce_alt_text.html',
        loadingText: 'OK, so, the text...',
        onComplete: Prototype.emptyFunction
      });
      ipe._regularCFET = ipe.checkForExternalText;
      ipe.checkForExternalText = function() {
        assert(5, ipe._collection.length);
        ipe._regularCFET();
        var editor = ipe._controls.editor;
        var text = editor.options[editor.selectedIndex].text.strip();
        assertEqual('OK, so, the text...', text);
      };
      Event.simulateMouse('newtbe', 'mouseover');
      Event.simulateMouse('newtbe', 'click');
      var editor = ipe._controls.editor;
      var text = editor.options[editor.selectedIndex].text.strip();
      assertEqual('There we go...', text);
      wait(2000, function() {
        assertEqual(2, editor.selectedIndex, 'Did not properly select item');
        ipe.dispose();
      });
    }},

    testDeprecationLayer: function() {with(this) {
      // FIXME: needs to be coded yet, doesn't it?
      var ipe = new Ajax.InPlaceCollectionEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { paramName: 'test',
        okButton: false, cancelLink: false
      });
      assertIdentical(false, ipe.options.okControl, 'OK control should be disabled');
      assertIdentical(false, ipe.options.cancelControl, 'Cancel control should be disabled');
      ipe.dispose();
      ipe = new Ajax.InPlaceCollectionEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { paramName: 'test',
        okLink: true, cancelButton: true
      });
      assertEqual('link', ipe.options.okControl, 'OK control should be a link');
      assertEqual('button', ipe.options.cancelControl, 'Cancel control should be a button');
      ipe.dispose();
      ipe = new Ajax.InPlaceCollectionEditor('newtbe',
        '_ajax_inplaceeditor_result2.html', { paramName: 'test',
        highlightcolor: '#ff0000', highlightendcolor: '#00ff00'
      });
      assertEqual('#ff0000', ipe.options.highlightColor, 'Highlight color was not migrated');
      assertEqual('#00ff00', ipe.options.highlightEndColor, 'Highlight end color was not migrated');
      ipe.dispose();
    }},


    testShouldShowAmpersandsProperly: function() {with(this) {
      var ipe = new Ajax.InPlaceEditor('contains_ampersand', '', {});
      Event.simulateMouse('contains_ampersand', 'click');
      assertEqual("Me & Myself", $$('form#contains_ampersand-inplaceeditor input.editor_field')[0].value);
      ipe.dispose();
    }}
    // FIXME: add AC w/o key conflicts?
    // FIXME: doc w/ full details on what's new, what's changed, etc. + deprecation layer info.
  });
// ]]>
</script>
</body>
</html>
